package aurora

import (
	"bytes"
	"encoding/json"
	"log"
	"reflect"
	"strings"
)

/*
	处理器结果 处理
*/

type result func(*proxy, interface{}, reflect.Value)

func stringResult(sp *proxy, v interface{}, value reflect.Value) {
	data := v.(string)
	if strings.HasSuffix(data, ".html") {
		HtmlPath := sp.pathPool.Get().(bytes.Buffer)
		if data[:1] == "/" {
			data = data[1:]
		}
		//拼接项目路径
		HtmlPath.WriteString(sp.projectRoot)
		//拼接 静态资源路径 默认情况下为 '/'
		HtmlPath.WriteString(sp.resource)
		//拼接 资源真实路径
		HtmlPath.WriteString(data)
		//得到完整 html 页面资源path
		html := HtmlPath.String()
		HtmlPath.Reset() //清空buffer，以便下次利用
		sp.pathPool.Put(HtmlPath)
		sp.rew.Header().Set(contentType, sp.resourceMapType[".html"])
		sp.view.view(html, sp.rew, nil) //视图解析 响应 html 页面
		return
	}
	//处理转发，重定向本质重新走一边路由，找到对应处理的方法
	if strings.HasPrefix(data, "forward:") {
		data = data[8:]
		//请求转发 会携带当前的 请求体 和上下文参数
		c, u, ctx := sp.router.urlRouter(sp.req.Method, data, sp.rew, sp.req, sp.ctx)
		sp.handle(c, u, sp.rew, sp.req, ctx)
		return
	}
	sp.rew.Write([]byte(data))
}

func structResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}
func sliceResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}
func intResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}
func float64Result(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}
func boolResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}
func mapResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}

func pointerResult(sp *proxy, v interface{}, value reflect.Value) {
	otherResult(sp, v, value)
}

func otherResult(sp *proxy, v interface{}, value reflect.Value) {
	of := value.Type()
	if of.Implements(sp.errType) {
		//错误捕捉
		sp.catchError(of, value)
		return
	}
	marshal, err := json.Marshal(v)
	if err != nil {
		log.Println(err.Error())
		return
	}
	sp.rew.Write(marshal)
}

func interfaceHandle(sp *proxy, v interface{}, value reflect.Value) {
	//判断接口是否实现了 error 返回接口的类型，绝大部分应该是错误接口
	//通过 Elem 方法可以反者获取到，接口的具体类型的值反射
	val := value.Elem()
	of := value.Type()
	if !of.Implements(sp.errType) {
		//没有实现,反射校验接口是否实现的小坑，实现接口的形式要和统一，比如 反射类型是指针，实现接口绑定的方式要是指针
		//此处可能返回 interface{} 的数据 没有实现error的当作数据 返回
		var marshal []byte
		switch v.(type) {
		case string:
			//对字符串不仅处理
			marshal = []byte(v.(string))
		default:
			s, err := json.Marshal(v)
			if err != nil {
				log.Println(err.Error())
				return
			}
			marshal = s
		}
		sp.rew.Write(marshal)
		return
	}
	//错误捕捉
	sp.catchError(of, val)
}
